Urban Heat Island · LST Anomaly · BT vs Rural

UHI – Urban Heat Island Index

The Urban Heat Island (UHI) index quantifies how much hotter urban areas are compared to their surrounding rural environment, using satellite-derived brightness temperature or land surface temperature.
مؤشر الجزر الحرارية الحضرية UHI يقيس مقدار ارتفاع درجة حرارة المناطق العمرانية مقارنة بالمناطق الريفية المحيطة، اعتمادًا على درجة حرارة السطح الحرارية من صور الأقمار الصناعية.

1. Scientific Concept

The Urban Heat Island (UHI) effect occurs when cities exhibit higher surface and air temperatures than nearby rural areas due to impervious surfaces (concrete, asphalt), reduced vegetation, and waste heat from human activities.

Simple per-pixel UHI Index (Surface Temperature Anomaly)

One practical way to map UHI from satellite thermal data is:

UHI = BTurban − BT̄rural °C above rural reference

  • BTurban – brightness temperature (or LST) at each pixel.
  • BT̄rural – mean BT (or LST) over non-urban / rural pixels.

Typical Interpretation

UHI (°C)Interpretation
< 0 Cooler than rural reference (parks, water bodies).
0 – 2 Weak urban heat island.
2 – 5 Moderate UHI – noticeable warming in built-up areas.
> 5 Strong UHI – very hot urban cores / industrial zones.

يمكن تعديل قيم الحدود حسب الإقليم والمناخ. الأهم هو مقارنة مدن مختلفة أو تحليل تطور UHI زمنيًا لنفس المدينة.

Main Applications

  • Assessing thermal comfort and health risks in cities.
  • Urban planning (green spaces, reflective roofs, ventilation corridors).
  • Monitoring climate change impacts on cities.
  • دمج UHI مع الكثافة السكانية لتحديد مناطق الأولوية للتدخل.

2. Data & Inputs

Thermal Data (BT / LST)

  • Landsat 8/9 TIRS: Band 10 (BT) ثم يمكن تصحيحه لـ LST.
  • MODIS / Sentinel-3: منتجات جاهزة لـ LST على نطاق إقليمي / عالمي.

Urban / Rural Mask

  • NDBI أو IBI من نفس الصورة لتمييز العمران.
  • أو منتجات غطاء أرضي مثل ESA WorldCover, MODIS Land Cover.

Best Practices

  • اختيار مشاهد صافية في فصل الصيف، وفترة بعد الظهر (أقصى تسخين).
  • تصحيح سحابة و ظل سحابة قبل حساب BT و UHI.
  • العمل على عدة تواريخ لرسم تطور UHI زمنياً.

Suggested Palette (UHI, °C)

[ "#0f172a", "#22c55e", "#eab308", "#f97316", "#b91c1c", "#7f1d1d" ]

3. Google Earth Engine Code – UHI (BT − rural mean)

// UHI – Urban Heat Island Index from Landsat 8
// 1) Compute Brightness Temperature (BT) in °C from Band 10
// 2) Use NDBI to separate urban vs rural
// 3) Compute mean BT over rural pixels as reference
// 4) UHI = BT_C - mean_rural_BT

var roi = geometry;   // Draw AOI (city + surroundings) as 'geometry'
Map.centerObject(roi, 10);

// -------------------------
// 1. Load Landsat 8 TOA
// -------------------------
var l8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_TOA")
  .filterBounds(roi)
  .filterDate("2023-06-01", "2023-09-30")        // warm season
  .filter(ee.Filter.lt("CLOUD_COVER", 20))
  .sort("CLOUD_COVER");

var img = ee.Image(l8.first()).clip(roi);

// Select needed bands: RED, NIR, SWIR1, TIR
var red  = img.select("B4");
var nir  = img.select("B5");
var swir = img.select("B6");    // SWIR1
var tir  = img.select("B10");   // Thermal band (radiance)

// -------------------------
// 2. Compute Brightness Temperature (BT) in °C
// -------------------------
var K1 = ee.Number(img.get("K1_CONSTANT_BAND_10"));
var K2 = ee.Number(img.get("K2_CONSTANT_BAND_10"));

var btK = tir.expression(
  "K2 / log(K1 / L + 1)",
  {
    "K1": K1,
    "K2": K2,
    "L" : tir
  }
).rename("BT_K");

var btC = btK.subtract(273.15).rename("BT_C");

// -------------------------
// 3. Simple NDBI for urban mask
//    NDBI = (SWIR - NIR) / (SWIR + NIR)
//    urban: NDBI > 0, rural: NDBI < 0
// -------------------------
var ndbi = swir.subtract(nir).divide(swir.add(nir)).rename("NDBI");

var urbanMask  = ndbi.gt(0);   // built-up candidates
var ruralMask  = ndbi.lt(0);   // non-urban (reference)

// -------------------------
// 4. Compute mean BT over rural pixels (reference)
// -------------------------
var ruralBT = btC.updateMask(ruralMask);

var ruralStats = ruralBT.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry: roi,
  scale: 30,
  maxPixels: 1e13
});

var ruralMean = ee.Number(ruralStats.get("BT_C"));
print("Mean rural BT (°C)", ruralMean);

// -------------------------
// 5. UHI index (°C above rural)
// -------------------------
var uhi = btC.subtract(ruralMean).rename("UHI_C");

// Urban-only UHI mask (optional)
var uhiUrban = uhi.updateMask(urbanMask);

// -------------------------
// 6. Visualization
// -------------------------
var btVis = {
  min: 15,
  max: 45,
  palette: ["#020617","#0f172a","#1d4ed8","#22c55e","#eab308","#f97316","#b91c1c"]
};

var uhiVis = {
  min: -2,
  max:  8,
  palette: ["#0f172a","#22c55e","#eab308","#f97316","#b91c1c","#7f1d1d"]
};

Map.addLayer(btC, btVis, "Brightness Temperature (°C)");
Map.addLayer(uhi, uhiVis, "UHI (BT - rural mean)");
Map.addLayer(uhiUrban, uhiVis, "UHI (urban mask)", false);

// -------------------------
// 7. Export UHI map
// -------------------------
Export.image.toDrive({
  image: uhi,
  description: "UHI_L8_BT_ruralMean",
  fileNamePrefix: "UHI_L8_BT_ruralMean",
  region: roi,
  scale: 30,
  crs: "EPSG:4326",
  maxPixels: 1e13
});